package auctionhausen

import grails.converters.JSON
import org.springframework.dao.DataIntegrityViolationException


class ListingController {

	static allowedMethods = [save: "POST", update: "POST", addBid: "POST", delete: "POST"]

	def listingService
	def bidService

	def index() {
		redirect(action: "list", params: params)
	}
	
	def list() {
		def now = new Date()
		params.sort = params.sort ?: "dateCreated"
		params.order = params.order ?: "desc"
		params.max = Math.min(params.int('max') ?: 5, 5)
		params.offset = params.offset ?: 0

		def validListings = Listing.findAllByEndDateGreaterThan(now, params)
		[listingInstanceList: validListings, listingInstanceTotal: Listing.countByEndDateGreaterThan(now)]
	}
	
	def mine() {
		params.sort = params.sort ?: "endDate"
		params.order = params.order ?: "desc"
		params.max = Math.min(params.int('max') ?: 5, 5)
		params.offset = params.offset ?: 0
		
		def user = Customer.get(session.user.id)

		def myListings = Listing.findAllBySeller(user, params)
		[listingInstanceList: myListings, listingInstanceTotal: myListings.size()]
	}

	def create() {
		[listingInstance: new Listing(params)]
	}

	def save() {
		def listingInstance = listingService.createListing(params)
		if (listingInstance.hasErrors()) {
			render(view: "create", model: [listingInstance: listingInstance])
			return
		}

		flash.message = message(code: 'default.created.message', args: [
			message(code: 'listing.label', default: 'Listing'),
			listingInstance.id
		])
		redirect(action: "show", id: listingInstance.id)
	}

	def addBid() {
		def addBidResponse = [:]
		addBidResponse.failed = false
		addBidResponse.expired = false
		def listingInstance = Listing.get(params.listing.id)
		def bidInstance = bidService.createBid(params)
		if (bidInstance.hasErrors()) {
			addBidResponse.failed = true
			if (listingService.isListingExpired(listingInstance)) {
				addBidResponse.expired = true
			}
			else {

				addBidResponse.message = message(code: 'bid.not.added.message', args: [
					bidInstance.amount,
					Bid.MINIMUM_BID_DIFFERENCE
				])
			}
		} else {
			addBidResponse.message = message(code: 'bid.added.message', args: [bidInstance.amount])
			addBidResponse.nextBidAmount = bidInstance.amount+Bid.MINIMUM_BID_DIFFERENCE
		}


		render addBidResponse as JSON
	}

	def show() {
		def listingInstance = Listing.get(params.id)
		if (!listingInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'listing.label', default: 'Listing'),
				params.id
			])
			redirect(action: "list")
			return
		}

		[listingInstance: listingInstance]
	}
	
	def getTopBids() {
		def listing = Listing.get(params.id)
		def bids = Bid.recentBidsOnListing(listing).list()
		
		render bids as JSON
	}

	def edit() {
		def listingInstance = Listing.get(params.id)
		if (!listingInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'listing.label', default: 'Listing'),
				params.id
			])
			redirect(action: "list")
			return
		}

		[listingInstance: listingInstance]
	}

	def update() {
		def listingInstance = Listing.get(params.id)
		if (!listingInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'listing.label', default: 'Listing'),
				params.id
			])
			redirect(action: "list")
			return
		}

		if (params.version) {
			def version = params.version.toLong()
			if (listingInstance.version > version) {
				listingInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
						[
							message(code: 'listing.label', default: 'Listing')]
						as Object[],
						"Another user has updated this Listing while you were editing")
				render(view: "edit", model: [listingInstance: listingInstance])
				return
			}
		}

		listingInstance.properties = params

		if (!listingInstance.save(flush: true)) {
			render(view: "edit", model: [listingInstance: listingInstance])
			return
		}

		flash.message = message(code: 'default.updated.message', args: [
			message(code: 'listing.label', default: 'Listing'),
			listingInstance.id
		])
		redirect(action: "show", id: listingInstance.id)
	}

	def delete() {
		def listingInstance = Listing.get(params.id)
		if (!listingInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'listing.label', default: 'Listing'),
				params.id
			])
			redirect(action: "list")
			return
		}

		try {
			listingInstance.delete(flush: true)
			flash.message = message(code: 'default.deleted.message', args: [
				message(code: 'listing.label', default: 'Listing'),
				params.id
			])
			redirect(action: "list")
		}
		catch (DataIntegrityViolationException e) {
			flash.message = message(code: 'default.not.deleted.message', args: [
				message(code: 'listing.label', default: 'Listing'),
				params.id
			])
			redirect(action: "show", id: params.id)
		}
	}

	def getCurrentMinimumBid() {
		render listingService.getCurrentMinimumBidForListing(params['listing_id']) as JSON
	}
}
